import json
from . import business
from . import security
from . import context
import scopt.util.message as msg_util
import scopt.util.i18n as i18n
from scopt.util.json_s import clear

_MODULES = (security,
            context,
            business)

I18N = {}

for module in _MODULES:
    I18N.update(module.I18N)


def firmware(config):
    return {'PORT:HTTP_IN': 'ROUTE:DEFAULT_IN',
            'DEFAULT_IN': [_deserializer,
                           _lang,
                           security.registry(config),
                           context.Context(config),
                           business.handle,
                           _serializer,
                           _finalizer]}


def exception_handler(data_packet, text):
    print('EEEEEE {0}'.format(text))
    return msg_util.exception(data_packet, 'scopt.error.general', text)


def _deserializer(data_packet):
    # TODO: if data_packet does not contains message, handle it
    raw_request = data_packet['message'].pop('raw_request')
    data_packet['message']['request'] = json.loads(raw_request)
    return data_packet


def _lang(data_packet):
    request = msg_util.get_request(data_packet)

    if 'language' in request['reqh']:
        language = request['reqh']['language'].replace('-', '_')
    else:
        language = 'en_EN'

    i18n.set_language(language)
    return data_packet


def _serializer(data_packet):
    request = msg_util.get_request(data_packet)
    message_id = request['reqh']['message_id']
    response = data_packet['message'].pop('response')
    response['resh']['message_id'] = message_id
    raw_response = json.dumps(response, default=clear)
    data_packet['message']['raw_response'] = raw_response
    return data_packet


def _finalizer(data_packet):
    if 'raw_response' in data_packet['message']:
        raw_response = data_packet['message']['raw_response']
    else:
        raw_response = {}

    f_data_packet = msg_util.out_data_packet()
    f_data_packet['id'] = data_packet['id']
    f_data_packet['message']['raw_response'] = raw_response
    return f_data_packet
